/**
 * @file proc.h
 * @date 23.04.26
 * @author xin
 * @brief 进程相关数据结构定义
 * @version 0.1
 * @status Stable
*/

/* 暂时剔除proc/cpu中用到锁、虚拟内存、文件、目录的数据结构 */

#include "types.h"
#include "param.h"
#include "riscv.h"

// 内核切换上下文时保存的寄存器
struct context {
    uint64 ra;
    uint64 sp;

    // 函数调用时保存的寄存器
    uint64 s0;
    uint64 s1;
    uint64 s2;
    uint64 s3;
    uint64 s4;
    uint64 s5;
    uint64 s6;
    uint64 s7;
    uint64 s8;
    uint64 s9;
    uint64 s10;
    uint64 s11;
};

// trap handling时每个进程保存的帧
// trap handling的代码在trampoline.S中
// 保存的内容包括所有通用整数寄存器和几个内核相关信息
struct trapframe {
  /*   0 */ uint64 kernel_satp;     // 内核页表
  /*   8 */ uint64 kernel_sp;       // 进程的内核栈顶指针
  /*  16 */ uint64 kernel_trap;     // usertrap()函数地址
  /*  24 */ uint64 epc;             // 保存返回用户模式时的PC
  /*  32 */ uint64 kernel_hartid;   // 保存内核的tp(内核id)
  /*  40 */ uint64 ra;
  /*  48 */ uint64 sp;
  /*  56 */ uint64 gp;
  /*  64 */ uint64 tp;
  /*  72 */ uint64 t0;
  /*  80 */ uint64 t1;
  /*  88 */ uint64 t2;
  /*  96 */ uint64 s0;
  /* 104 */ uint64 s1;
  /* 112 */ uint64 a0;
  /* 120 */ uint64 a1;
  /* 128 */ uint64 a2;
  /* 136 */ uint64 a3;
  /* 144 */ uint64 a4;
  /* 152 */ uint64 a5;
  /* 160 */ uint64 a6;
  /* 168 */ uint64 a7;
  /* 176 */ uint64 s2;
  /* 184 */ uint64 s3;
  /* 192 */ uint64 s4;
  /* 200 */ uint64 s5;
  /* 208 */ uint64 s6;
  /* 216 */ uint64 s7;
  /* 224 */ uint64 s8;
  /* 232 */ uint64 s9;
  /* 240 */ uint64 s10;
  /* 248 */ uint64 s11;
  /* 256 */ uint64 t3;
  /* 264 */ uint64 t4;
  /* 272 */ uint64 t5;
  /* 280 */ uint64 t6;
};

// 进程存在状态
enum procstate {UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE};

// 进程
struct proc
{
    enum procstate state;       // 进程当前的状态
    // 一种资源，可能是进程、文件描述符、设备
    // 若得不到使用，则进程会为此sleep
    // 直到释放该资源时wakeup等待该资源的所有进程
    // 为0代表未sleep
    void *chan;                 
    int killed;                 // 是否被killed
    int xstate;                 // 子进程exit()时的状态
    int pid;                    // 进程ID

    struct proc *parent;        // 父进程

    // 以下内容属于进程私有
    uint64 kstack;              // 内核栈的虚拟地址           
    uint64 sz;                  // 进程在内存中的size(byte) (实则是页表的大小)
    pagetable_t pagetable;      // 用户的页表                   
    struct trapframe *trapframe;// 处理trap时上下文帧
    struct context context;     // 上下文 
    struct file *ofile[NOFILE]; // 打开的文件                 
    struct inode *cwd;          // 当前所在目录               
    char name[16];              // 进程名称
};


// 每个CPU保存的数据结构
struct cpu {
    struct proc *proc;          // 在该CPU上运行的进程
    struct context context;     // 调度中切换进程时进程用于切换的上下文信息
    // 暂未用到锁机制，不存在push_off()嵌套的深度
//    int noff;                   // push_off()嵌套深度
//    int intena;                 // 在push_off()前是否启用了中断
};

extern struct cpu cpus[NCPU];